package io.gitee.kotle.android.library.websocket.impl.okhttp

import io.gitee.kotle.android.library.websocket.WebSocketConnectError
import io.gitee.kotle.android.library.websocket.WebSocketStatus
import io.gitee.kotle.android.library.websocket.impl.BaseWebSocket
import okhttp3.*
import okio.ByteString
import java.nio.charset.Charset

/**
 *
 * 描述：
 *
 * @author jiale.wei
 *
 * 创建时间：2022/8/10 15:45
 *
 */
class OkHttpWebSocketImpl(private val client: OkHttpClient) : BaseWebSocket() {
    private var socket: WebSocket? = null
    private val listener = object : WebSocketListener() {
        override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosed(webSocket, code, reason)
        }

        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            super.onClosing(webSocket, code, reason)
            eachListener {
                it.onConnectStatus(WebSocketStatus.ConnectFail(WebSocketConnectError(code, reason)))
            }
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            super.onFailure(webSocket, t, response)
            eachListener {
                it.onConnectStatus(
                    WebSocketStatus.ConnectFail(
                        WebSocketConnectError(
                            -1,
                            t.message ?: ""
                        )
                    )
                )
            }
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            super.onMessage(webSocket, text)
            eachListener {
                it.onMessage(text)
            }
        }

        override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
            super.onMessage(webSocket, bytes)
            eachListener {
                it.onMessage(bytes.string(Charset.defaultCharset()))
            }
        }

        override fun onOpen(webSocket: WebSocket, response: Response) {
            super.onOpen(webSocket, response)
            eachListener {
                it.onConnectStatus(WebSocketStatus.ConnectSuccess)
            }
        }
    }

    override fun connect(wsUrl: String) {
        val request = Request.Builder()
            .url(wsUrl)
            .build()
        socket = client.newWebSocket(request, listener)
    }

    override fun send(message: String): Boolean {
        return socket?.send(message) == true
    }

    override fun disConnect() {
        socket?.cancel()
        socket = null
    }
}